<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import * as monaco from "monaco-editor";
import { ElMessage } from "element-plus";

const props = defineProps({
  value: {
    type: [Object, Array],
    required: true
  },
  height: {
    type: Number,
    default: 400
  },
  readOnly: {
    type: Boolean,
    default: false
  }
});

const emit = defineEmits(["save"]);

const editorRef = ref<HTMLElement>();
let editor: monaco.editor.IStandaloneCodeEditor;

// 初始化编辑器
onMounted(() => {
  if (editorRef.value) {
    editor = monaco.editor.create(editorRef.value, {
      value: JSON.stringify(props.value, null, 2),
      language: "json",
      theme: "vs",
      automaticLayout: true,
      minimap: { enabled: false },
      scrollBeyondLastLine: false,
      readOnly: props.readOnly,
      fontSize: 14,
      tabSize: 2,
      lineNumbers: "on",
      roundedSelection: false,
      scrollbar: {
        vertical: "visible",
        horizontal: "visible",
        useShadows: false,
        verticalScrollbarSize: 10,
        horizontalScrollbarSize: 10
      }
    });

    // 添加保存快捷键
    editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
      handleSave();
    });
  }
});

// 监听值变化
watch(
  () => props.value,
  newVal => {
    if (editor && newVal) {
      const currentValue = editor.getValue();
      const newValue = JSON.stringify(newVal, null, 2);
      if (currentValue !== newValue) {
        editor.setValue(newValue);
      }
    }
  },
  { deep: true }
);

// 保存
const handleSave = () => {
  try {
    const value = editor.getValue();
    const jsonValue = JSON.parse(value);
    emit("save", jsonValue);
  } catch (error) {
    ElMessage.error("JSON格式错误");
  }
};

// 格式化
const formatJson = () => {
  try {
    const value = editor.getValue();
    const jsonValue = JSON.parse(value);
    editor.setValue(JSON.stringify(jsonValue, null, 2));
    ElMessage.success("格式化成功");
  } catch (error) {
    ElMessage.error("JSON格式错误");
  }
};
</script>

<template>
  <div class="json-editor">
    <div class="toolbar">
      <el-button type="primary" @click="handleSave"> 保存 </el-button>
      <el-button @click="formatJson"> 格式化 </el-button>
      <div class="tips">
        <el-tag size="small" type="info"> 提示: 按 Ctrl + S 快捷保存 </el-tag>
      </div>
    </div>
    <div
      ref="editorRef"
      class="monaco-editor"
      :style="{ height: `${height}px` }"
    />
  </div>
</template>

<style lang="scss" scoped>
.json-editor {
  .toolbar {
    display: flex;
    gap: 12px;
    align-items: center;
    margin-bottom: 12px;

    .tips {
      margin-left: auto;
    }
  }

  .monaco-editor {
    border: 1px solid var(--el-border-color);
    border-radius: 4px;
  }
}
</style>
